package com.ruoyi.project.fusion.algorithms;

import com.ruoyi.project.fusion.domain.ServiceAggInfo;
import com.ruoyi.project.fusion.domain.ServiceScores;
import com.ruoyi.project.fusion.utils.ComputeUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class ServiceAlgorithm {
    public List<ServiceScores> compute(List<ServiceAggInfo> serviceAggInfos) {
        List<ServiceScores> scoresList = new ArrayList<>();

        // 按照 chainType、scenario、product 分组
        Map<List<String>, List<ServiceAggInfo>> groupedInfos = serviceAggInfos.stream()
                .collect(Collectors.groupingBy(info -> Arrays.asList(
                        info.getChainType(),
                        info.getScenario(),
                        info.getProduct(),
                        info.getEvent()
                )));

        for (Map.Entry<List<String>, List<ServiceAggInfo>> entry : groupedInfos.entrySet()) {
            List<ServiceAggInfo> group = entry.getValue();

            // 归一化数据
            List<Double> normalizedCustomerCount = ComputeUtils.normalizeValues(group.stream().map(ServiceAggInfo::getAvgCustomerCount).collect(Collectors.toList()));
            List<Double> normalizedMarketShare = ComputeUtils.normalizeValues(group.stream().map(ServiceAggInfo::getAvgMarketShare).collect(Collectors.toList()));
            List<Double> normalizedAnnualSales =ComputeUtils. normalizeValues(group.stream().map(ServiceAggInfo::getAvgAnnualSales).collect(Collectors.toList()));
            List<Double> normalizedCustomerSatisfaction = ComputeUtils.normalizeValues(group.stream().map(ServiceAggInfo::getAvgCustomerSatisfaction).collect(Collectors.toList()));
            List<Double> normalizedCustomerComplaintRate = ComputeUtils.normalizeValues(group.stream().map(ServiceAggInfo::getAvgCustomerComplaintRate).collect(Collectors.toList()));
            List<Double> normalizedCustomerRepurchaseRate = ComputeUtils.normalizeValues(group.stream().map(ServiceAggInfo::getAvgCustomerRepurchaseRate).collect(Collectors.toList()));
            List<Double> normalizedOrderProcessingTime = ComputeUtils.normalizeValues(group.stream().map(ServiceAggInfo::getAvgOrderProcessingTime).collect(Collectors.toList()));
            List<Double> normalizedDeliveryTime = ComputeUtils.normalizeValues(group.stream().map(ServiceAggInfo::getAvgDeliveryTime).collect(Collectors.toList()));

            // 计算各项指标的标准差
            double stdDevCustomerCount = ComputeUtils.calculateStandardDeviation(normalizedCustomerCount);
            double stdDevMarketShare = ComputeUtils.calculateStandardDeviation(normalizedMarketShare);
            double stdDevAnnualSales = ComputeUtils.calculateStandardDeviation(normalizedAnnualSales);
            double stdDevCustomerSatisfaction = ComputeUtils.calculateStandardDeviation(normalizedCustomerSatisfaction);
            double stdDevCustomerComplaintRate = ComputeUtils.calculateStandardDeviation(normalizedCustomerComplaintRate);
            double stdDevCustomerRepurchaseRate = ComputeUtils.calculateStandardDeviation(normalizedCustomerRepurchaseRate);
            double stdDevOrderProcessingTime = ComputeUtils.calculateStandardDeviation(normalizedOrderProcessingTime);
            double stdDevDeliveryTime = ComputeUtils.calculateStandardDeviation(normalizedDeliveryTime);

            // 计算总标准差
            double totalStdDev = stdDevCustomerCount + stdDevMarketShare + stdDevAnnualSales + stdDevCustomerSatisfaction +
                    stdDevCustomerComplaintRate + stdDevCustomerRepurchaseRate + stdDevOrderProcessingTime + stdDevDeliveryTime;

            // 计算权重
            double weightCustomerCount = (totalStdDev == 0) ? 0.125 : stdDevCustomerCount / totalStdDev;
            double weightMarketShare = (totalStdDev == 0) ? 0.125 : stdDevMarketShare / totalStdDev;
            double weightAnnualSales = (totalStdDev == 0) ? 0.125 : stdDevAnnualSales / totalStdDev;
            double weightCustomerSatisfaction = (totalStdDev == 0) ? 0.125 : stdDevCustomerSatisfaction / totalStdDev;
            double weightCustomerComplaintRate = (totalStdDev == 0) ? 0.125 : stdDevCustomerComplaintRate / totalStdDev;
            double weightCustomerRepurchaseRate = (totalStdDev == 0) ? 0.125 : stdDevCustomerRepurchaseRate / totalStdDev;
            double weightOrderProcessingTime = (totalStdDev == 0) ? 0.125 : stdDevOrderProcessingTime / totalStdDev;
            double weightDeliveryTime = (totalStdDev == 0) ? 0.125 : stdDevDeliveryTime / totalStdDev;

            // 计算分数
            for (int i = 0; i < group.size(); i++) {
                ServiceAggInfo info = group.get(i);

                double score = (normalizedCustomerCount.get(i) * weightCustomerCount) +
                        (normalizedMarketShare.get(i) * weightMarketShare) +
                        (normalizedAnnualSales.get(i) * weightAnnualSales) +
                        (normalizedCustomerSatisfaction.get(i) * weightCustomerSatisfaction) +
                        (normalizedCustomerComplaintRate.get(i) * weightCustomerComplaintRate) +
                        (normalizedCustomerRepurchaseRate.get(i) * weightCustomerRepurchaseRate) +
                        (normalizedOrderProcessingTime.get(i) * weightOrderProcessingTime) +
                        (normalizedDeliveryTime.get(i) * weightDeliveryTime);

                ServiceScores serviceScore = new ServiceScores();
                serviceScore.setChainType(info.getChainType());
                serviceScore.setEnterpriseName(info.getEnterpriseName());
                serviceScore.setScenario(info.getScenario());
                serviceScore.setProduct(info.getProduct());
                serviceScore.setEvent(info.getEvent());
                serviceScore.setScore(ComputeUtils.roundToTwoDecimalPlaces((float) score));

                scoresList.add(serviceScore);
            }
        }

        return scoresList;
    }
}
